<p>The Devs plugin provides you with ready-to-use shapes with predefined input &amp; output port groups and simplified API.</p>

<h3>joint.shapes.devs.Model</h3>

<p>The Model shape implements simple API on top of the JointJS built-in ports. It splits ports into two semantic groups (<b>in</b> and <b>out</b>) and adds convenient methods for adding and removing ports.</p>

<table>
    <tr>
      <th>inPorts</th>
      <td>an array of all input ports</td>
    </tr>
    <tr>
      <th>outPorts</th>
      <td>an array of all output ports</td>
    </tr>
</table>


<h5 id="shapes.devs.Model.addInPort">shapes.devs.Model.addInPort</h5>
<pre class="docs-method-signature"><code>element.addInPort(port, [opt])</code></pre>
<p>Add a single port into the `inPorts` array, where `port` is a name of the port.</p>

<h5 id="shapes.devs.Model.addOutPort">shapes.devs.Model.addOutPort</h5>
<pre class="docs-method-signature"><code>element.addOutPort(port, [opt])</code></pre>
<p>Add a single port into the `outPorts` array, where `port` is a name of the port.</p>

<h5 id="shapes.devs.Model.changeInGroup">shapes.devs.Model.changeInGroup</h5>
<pre class="docs-method-signature"><code>element.changeInGroup(properties, [opt])</code></pre>
<p>Change the settings for the input ports, where `properties` is an object with a <a href="#dia.Element.ports.interface">group configuration</a>. It extends the previous settings with the new configuration by default. Pass <code>{ rewrite: true }</code> via <code>opt</code> to invalidate the previous settings.</p>

<h5 id="shapes.devs.Model.changeOutGroup">shapes.devs.Model.changeOutGroup</h5>
<pre class="docs-method-signature"><code>element.changeOutGroup(properties, [opt])</code></pre>
<p>Change the settings for the output ports, where `properties` is an object with a <a href="#dia.Element.ports.interface">group configuration</a>. It extends the previous settings with the new configuration by default. Pass <code>{ rewrite: true }</code> via <code>opt</code> to invalidate the previous settings.</p>

<h5 id="shapes.devs.Model.removeInPort">shapes.devs.Model.removeInPort</h5>
<pre class="docs-method-signature"><code>element.removeInPort(port, [opt])</code></pre>
<p>Remove a port from an element from the `inPorts` array, where `port` is a name of the port.</p>

<h5 id="shapes.devs.Model.removeOutPort">shapes.devs.Model.removeOutPort</h5>
<pre class="docs-method-signature"><code>element.removeOutPort(port, [opt])</code></pre>
<p>Remove a port from an element from the `outPorts` array, where `port` is a name of the port.</p>

<h3>joint.shapes.devs.Link</h3>

<p>The <code>devs.Link</code> extends the <code>joint.dia.Link</code> and changes the link appearance.</p>


<h4>Example usage</h4>

<pre><code>var shape = new joint.shapes.devs.Model({
    position: {
        x: 100,
        y: 100
    },
    inPorts: ['in1', 'in2'],
    outPorts: ['out1', 'out2']
});

shape.addTo(graph);

// adding/removing ports dynamically
shape.addInPort('in3');
shape.removeOutPort('out1').addOutPort('out3');

var link = new joint.shapes.devs.Link({
    source: {
        id: shape.id,
        port: 'out3'
    },
    target: {
        x: 200,
        y: 300
    }
});
link.addTo(graph);

// moving the input ports from `left` to `top`
shape.changeInGroup({ position: 'top' });
// moving the output ports 'right' to 'bottom'
shape.changeOutGroup({ position: 'bottom' });
</code></pre>

<h4 id="shapes.devs.hierarchical_diagrams">Hierarchical diagrams</h4>

<p>There are two more shapes designed for hierarchical diagrams as part of the plugin - <code>devs.Atomic</code> and <code>devs.Coupled</code>. They inherit from the <code>devs.Model</code> and differ only in the color and size. The purpose of these shapes is to enable you to implement a custom logic in your application based on their type.
For instance a <code>devs.Coupled</code> can embed <code>devs.Atomic</code>'s but not the other way round as shown in the demo below.</p>

<p>When working with hierarchical diagrams there is a few methods, that might come in handy.</p>

<p><a href="#dia.Element.prototype.embed"><code>coupled.embed(atomic)</code></a> that can put the `atomic` shape into the `coupled`.</p>

<p><a href="#dia.Element.prototype.fitEmbeds"><code>coupled.fitEmbeds()</code></a> that resizes the `coupled` shape, so it visually contains all shapes embedded in.</p>

<p><a href="#dia.Link.prototype.reparent"><code>link.reparent()</code></a> that finds the best parent for the `link` based on the source and target element.</p>

<iframe src="about:blank" data-src="./demo/shapes/shapes.devs.html" style="height: 404px; width: 803px;"></iframe>
